package com.qcby.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

// 事务注解，用于标记需要事务管理的方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Transactional {
}

// 事务管理器，负责事务的开始、提交和回滚
class TransactionManager {
    // 使用 ThreadLocal 保存每个线程的事务状态
    private static ThreadLocal<Map<String, Integer>> transactionState = new ThreadLocal<>();

    // 开始事务
    public static void begin() {
        System.out.println("开始事务");
        // 获取当前账户状态的副本
        Map<String, Integer> state = new HashMap<>(getCurrentAccounts());
        transactionState.set(state);
    }

    // 提交事务
    public static void commit() {
        System.out.println("事务提交成功");
        transactionState.remove();
    }

    // 回滚事务
    public static void rollback() {
        System.out.println("执行回滚操作");
        // 恢复到事务开始前的状态
        Map<String, Integer> state = transactionState.get();
        if (state != null) {
            getCurrentAccounts().clear();
            getCurrentAccounts().putAll(state);
        }
        transactionState.remove();
    }

    // 获取当前账户数据的引用
    private static Map<String, Integer> getCurrentAccounts() {
        // 通过 ServiceContext 获取当前的账户实例
        // 这里简化处理，实际项目中可以使用更复杂的依赖注入机制
        return ServiceContext.getAccountService().getAccounts();
    }
}

// 服务上下文，用于管理服务实例
class ServiceContext {
    private static AccountService accountService;

    public static void setAccountService(AccountService service) {
        accountService = service;
    }

    public static AccountService getAccountService() {
        return accountService;
    }
}

// 账户服务接口
interface AccountService {
    // 获取账户数据的方法
    Map<String, Integer> getAccounts();

    void transfer(String from, String to, int amount) throws Exception;
}

// 账户服务实现
class AccountServiceImpl implements AccountService {
    private final Map<String, Integer> accounts;

    // 通过构造函数注入账户数据
    public AccountServiceImpl(Map<String, Integer> accounts) {
        this.accounts = accounts;
        // 在服务初始化时设置到上下文
        ServiceContext.setAccountService(this);
    }

    @Override
    public Map<String, Integer> getAccounts() {
        return accounts;
    }

    @Override
    @Transactional
    public void transfer(String from, String to, int amount) throws Exception {
        // 检查余额
        if (accounts.get(from) < amount) {
            throw new Exception("余额不足");
        }

        // 模拟可能出现的异常（30%概率抛出异常）
        if (Math.random() > 0.7) {
            throw new RuntimeException("系统故障，随机回滚");
        }

        // 执行转账操作
        accounts.put(from, accounts.get(from) - amount);
        accounts.put(to, accounts.get(to) + amount);
        System.out.println("执行转账: " + from + " -> " + to + " 金额: " + amount);
    }
}

// 事务代理处理器
class TransactionInvocationHandler implements InvocationHandler {
    private final Object target;

    public TransactionInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 检查方法是否有 @Transactional 注解
        if (method.isAnnotationPresent(Transactional.class)) {
            try {
                // 开始事务
                TransactionManager.begin();

                // 执行目标方法
                Object result = method.invoke(target, args);

                // 提交事务
                TransactionManager.commit();

                return result;
            } catch (InvocationTargetException e) {
                // 回滚事务
                TransactionManager.rollback();
                throw e.getCause();
            } catch (Exception e) {
                // 回滚事务
                TransactionManager.rollback();
                throw e;
            }
        } else {
            // 无事务注解，直接执行方法
            return method.invoke(target, args);
        }
    }
}

// 代理工厂
class ProxyFactory {
    public static <T> T createProxy(Class<T> interfaceClass, T target) {
        return (T) Proxy.newProxyInstance(
                interfaceClass.getClassLoader(),
                new Class<?>[]{interfaceClass},
                new TransactionInvocationHandler(target)
        );
    }
}

// 主类测试
public class DynamicProxyTransactionDemo {
    public static void main(String[] args) {
        // 初始化账户
        Map<String, Integer> accounts = new HashMap<>();
        accounts.put("A", 100);
        accounts.put("B", 200);

        System.out.println("初始状态: A=" + accounts.get("A") + ", B=" + accounts.get("B"));

        // 创建原始服务实例，注入账户数据
        AccountService service = new AccountServiceImpl(accounts);

        // 创建代理服务
        AccountService proxyService = ProxyFactory.createProxy(AccountService.class, service);

        // 执行事务性转账
        try {
            proxyService.transfer("A", "B", 50);
            System.out.println("转账成功！");
        } catch (Exception e) {
            System.out.println("转账失败: " + e.getMessage());
        }

        System.out.println("第一次转账后: A=" + accounts.get("A") + ", B=" + accounts.get("B"));

        // 再次执行事务（可能触发回滚）
        try {
            proxyService.transfer("B", "A", 100);
            System.out.println("转账成功！");
        } catch (Exception e) {
            System.out.println("转账失败: " + e.getMessage());
        }

        System.out.println("第二次转账后: A=" + accounts.get("A") + ", B=" + accounts.get("B"));
    }
}